﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
using Charts.QuickChart.Data;
using Client.App.ViewModels.Interfaces;
using Core.Mvvm.ViewModels;
using Multiprocessing.Core.Algorithm;
using Multiprocessing.Core.Units;

namespace Client.App.ViewModels.Implementations
{
    public class DataTimeTestViewModel : BaseTestViewModel, IDataTimeTestViewModel
    {
        #region Fields

        private int _maxSize;
        private int _stepCount;
        private string _horizontalTitle;
        private string _verticalTitle;
        private IDataPointCollection<double, double> _analyzeResult; 

        #endregion

        #region Properties

        public IDataPointCollection<double, double> AnalyzeResult
        {
            get { return _analyzeResult; }
            set { SetProperty(ref _analyzeResult, value, () => this.AnalyzeResult); }
        }

        public string HorizontalTitle
        {
            get { return _horizontalTitle; }
            set { SetProperty(ref _horizontalTitle, value, () => this.HorizontalTitle); }
        }

        public string VerticalTitle
        {
            get { return _verticalTitle; }
            set { SetProperty(ref _verticalTitle, value, () => this.VerticalTitle); }
        }

        public int StepCount
        {
            get { return _stepCount; }
            set { SetProperty(ref _stepCount, value, () => this.StepCount); }
        }

        public int MaxSize
        {
            get { return _maxSize; }
            set { SetProperty(ref _maxSize, value, () => this.MaxSize); }
        }

        #endregion

        #region Constructors

        public DataTimeTestViewModel(Dispatcher dispatcher) 
            : base(dispatcher)
        {
            this.HorizontalTitle = "Количество данных";
        }

        #endregion

        #region Methods

        protected override void OnAnalyze()
        {
            int sizeIncrement = this.MaxSize/this.StepCount;

            this.IsAnalyzing = true;
            List<Tuple<int, TimeSpan>> resultList = new List<Tuple<int, TimeSpan>>(StepCount);
            for (int size = sizeIncrement + this.MaxSize%this.StepCount;
                 size < this.MaxSize;
                 size += sizeIncrement)
            {
                object[] args = this.Algorithm.CreateParameters(size);
                AlgorithmResult result =
                    this.Algorithm.Execute<TaskProcessingBlock  >(args);
                resultList.Add(new Tuple<int, TimeSpan>(size, result.ElapsedTime));
            }
            // seconds or milliseconds?
            if (resultList.All(t => t.Item2.TotalSeconds < 1.0))
            {
                this.AnalyzeResult =
                    new UnorderedDataPointCollection<double, double>(
                        resultList.Select(t => new DataPoint<double, double>(t.Item1, t.Item2.TotalMilliseconds)).ToList());
                this.VerticalTitle = "Milliseconds, ms";
            }
            else
            {
                this.AnalyzeResult =
                    new UnorderedDataPointCollection<double, double>(
                        resultList.Select(t => new DataPoint<double, double>(t.Item1, t.Item2.TotalSeconds)).ToList());
                this.VerticalTitle = "Seconds, s";
            }

            this.IsAnalyzing = false;
        }
    
        #endregion
    }
}
